package com.winter.common;

import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 条形码生成和识别工具
 */
public class BarCodeUtils {

    public static void main(String[] args) throws Exception {
        String imgPath = "/Users/sten/Desktop/123.jpg";
        String contents = "6943620593115";
        int width = 105, height = 100;
        encode(contents, width, height, imgPath);

        String imgPath2 = "/Users/sten/Desktop/123.jpg";
        String decodeContent = decode(imgPath2);
        System.out.println("解码内容如下：");
        System.out.println(decodeContent);
    }

    public static void encode(String contents, int width, int height, String imgPath) throws IOException, WriterException {
        int codeWidth = 3 + // start guard
                (7 * 6) + // left bars
                5 + // middle guard
                (7 * 6) + // right bars
                3; // end guard
        codeWidth = Math.max(codeWidth, width);
        Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
        // 指定编码格式
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");

        BitMatrix bitMatrix = new MultiFormatWriter().encode(contents,
                BarcodeFormat.CODE_128, codeWidth, height, hints);


        File path = new File(imgPath);
        MatrixToImageWriter.writeToFile(bitMatrix, "png", path);
    }

    /**
     * 生成条形码
     *
     * @param contents
     * @param width
     * @param height
     * @return
     * @throws WriterException
     */
    public static BitMatrix encode(String contents, int width, int height) throws WriterException {
        int codeWidth = 3 + // start guard
                (7 * 6) + // left bars
                5 + // middle guard
                (7 * 6) + // right bars
                3; // end guard
        codeWidth = Math.max(codeWidth, width);
        Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
        // 指定编码格式
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");

        return new MultiFormatWriter().encode(contents,
                    BarcodeFormat.CODE_128, codeWidth, height, null);
    }

    /**
     *  识别条形码数据
     */
    public static String decode(String imgPath) throws Exception {
        BufferedImage image = ImageIO.read(new File(imgPath));
        if (image == null) {
            throw new Exception("the decode image may be not exit.") ;
        }
        LuminanceSource source = new BufferedImageLuminanceSource(image);
        BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));

        Result result = new MultiFormatReader().decode(bitmap, null);
        return result.getText();
    }
}
